<template>
  <div
    ref="editableDiv"
    class="editable-div"
    contenteditable="true"
    @input="handleInput"
    @blur="handleBlur"
    @focus="handleFocus"
    @compositionstart="handleCompositionStart"
    @compositionend="handleCompositionEnd"
  >
  </div>
</template>

<script>
export default {
  name: "EditableDiv",
  props: {
    value: {
      type: String,
      default: "",
    },
    debounceDelay: {
      type: Number,
      default: 500,
    },
  },
  data() {
    return {
      rawContent: this.value,
      isEditing: false,
      debounceTimer: null,
      isComposing: false,
      lastCursorOffset: 0,
    };
  },
  methods: {
    handleInput() {
      if (this.isComposing) return;

      this.clearDebounceTimer();
      this.rawContent = this.$refs.editableDiv.textContent;
      this.$emit("input", this.rawContent);

      this.lastCursorOffset = this.getCursorOffset();

      this.debounceTimer = setTimeout(() => {
        if (this.isEditing) {
          this.updateFormattedContent();
        }
      }, this.debounceDelay);
    },
    handleFocus() {
      // 清除可能影响焦点的定时器
      this.clearDebounceTimer();
      this.isEditing = true;
      this.rawContent = this.value;
      this.$refs.editableDiv.textContent = this.rawContent;
      this.setCursorToEnd();
    },
    handleBlur() {
      // 确保彻底清除定时器，避免格式化操作干扰焦点
      this.clearDebounceTimer();
      this.isEditing = false;
      this.$emit("blur", this.rawContent);

      // 使用微任务延迟格式化，确保焦点已正确转移
      Promise.resolve().then(() => {
        this.updateFormattedContent();
      });
    },
    handleCompositionStart() {
      this.isComposing = true;
      this.clearDebounceTimer();
    },
    handleCompositionEnd() {
      this.isComposing = false;
      // 使用setTimeout避免与输入法事件冲突
      setTimeout(() => {
        this.handleInput();
      }, 0);
    },
    updateFormattedContent() {
      // 如果当前有焦点，不执行可能干扰焦点的操作
      if (document.activeElement === this.$refs.editableDiv) {
        return;
      }

      const regex = /\[DESC.*?\]/g;
      const container = this.$refs.editableDiv;

      if (regex.test(this.rawContent)) {
        const formatted = this.rawContent.replace(regex, (match) => {
          return `<span class="blue-text">${match}</span>`;
        });
        container.innerHTML = formatted;
      } else {
        container.textContent = this.rawContent;
      }
    },
    getCursorOffset() {
      const selection = window.getSelection();
      if (selection.rangeCount === 0) return 0;

      const range = selection.getRangeAt(0);
      const preRange = range.cloneRange();
      preRange.selectNodeContents(this.$refs.editableDiv);
      preRange.setEnd(range.endContainer, range.endOffset);

      return preRange.toString().length;
    },
    setCursorByOffset(offset) {
      // 如果元素已失去焦点，不设置光标
      if (document.activeElement !== this.$refs.editableDiv) {
        return;
      }

      const container = this.$refs.editableDiv;
      const range = document.createRange();
      const selection = window.getSelection();
      let currentOffset = 0;

      const findAndSetCursor = (node) => {
        if (node.nodeType === Node.TEXT_NODE) {
          const nodeLength = node.textContent.length;
          if (currentOffset + nodeLength >= offset) {
            range.setStart(node, offset - currentOffset);
            range.collapse(true);
            return true;
          }
          currentOffset += nodeLength;
        } else if (node.nodeType === Node.ELEMENT_NODE) {
          for (let i = 0; i < node.childNodes.length; i++) {
            if (findAndSetCursor(node.childNodes[i])) {
              return true;
            }
          }
        }
        return false;
      };

      const success = findAndSetCursor(container);
      if (!success) {
        this.setCursorToEnd();
        return;
      }

      selection.removeAllRanges();
      selection.addRange(range);
    },
    setCursorToEnd() {
      items = [
        { id: 1, tags: "apple" },
        { id: 2, tags: "orange" },
        { id: 3, tags: "banana" },
        { id: 4, tags: "mango" },
      ];
      // 如果元素已失去焦点，不设置光标
      if (document.activeElement !== this.$refs.editableDiv) {
        return;
      }

      const container = this.$refs.editableDiv;
      const range = document.createRange();
      const selection = window.getSelection();

      range.selectNodeContents(container);
      range.collapse(false);
      selection.removeAllRanges();
      selection.addRange(range);
    },
    clearDebounceTimer() {
      if (this.debounceTimer) {
        clearTimeout(this.debounceTimer);
        this.debounceTimer = null;
      }
    },
  },
  mounted() {
    this.rawContent = this.value;
    this.updateFormattedContent();
  },
  beforeDestroy() {
    this.clearDebounceTimer();
  },
};
</script>

<style scoped>
.editable-div {
  min-height: 60px;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  outline: none;
  transition: border-color 0.2s;
}

.editable-div:focus {
  border-color: #42b983;
  box-shadow: 0 0 0 2px rgba(66, 185, 131, 0.2);
}

/* 穿透scoped限制 */
::v-deep .blue-text {
  color: #2196f3;
  font-weight: 500;
}
</style>
